#pragma once
#include "CriticalSection.h"

namespace WTB{

	class CFreeList{
	private:
		static const int PER_MEMORY_ARRAY_LEN = 512;
		static const int DEFAULT_MEMORY_ARRAY_POINT_ARRAY_LEN = 128;
	public:
		CFreeList():
		  m_MemoryArrayPointArray(NULL),
			  m_nCurrentMemoryArrayPointArrayLen(0),
			  m_nCurrentMemoryArrayPointArrayUsedLen(0),
			  m_nPerMemorySize(0),
			  m_FreeListHead(NULL)	
		  {

		  }
		  ~CFreeList(){
			  UnInit();
		  }

		  int Init(int _nPerMemorySize);

		  void UnInit();

		  /*
		  * get a _nByte size memory(all set to 0) in support of multi-thread
		  *
		  *@return the base address of the memory(success) or NULL(failure)
		  *
		  */
		  char* GetMemory(int _nByte);

		  /*
		  * release a _nByte size memory in support of multi-thread
		  *
		  *@parm _memory base address of the memory to release
		  *
		  *@return 0(success),-1(failure)
		  *
		  */
		  int	ReleaseMemory(char* _memory,int _nByte);

	private:
		char** m_MemoryArrayPointArray;
		int m_nCurrentMemoryArrayPointArrayLen;
		int m_nCurrentMemoryArrayPointArrayUsedLen;
		int m_nPerMemorySize;
		char* m_FreeListHead;

		CCriticalSection m_objCriticalSection;
	};

	class CFreeListPool
	{
	private:
		static const int FREE_LIST_ARRAY_LEN = 64;
		static const int MIN_MEMORY_SLICE_SIZE = 8;
		static const int MAX_MEMORY_SLICE_SIZE = MIN_MEMORY_SLICE_SIZE * FREE_LIST_ARRAY_LEN;

	protected:
		CFreeListPool(void);

		int Init();

		void UnInit();

	public:
		static CFreeListPool* Instance(){
			static CFreeListPool freeListPool;
			return &freeListPool;
		}
		~CFreeListPool(void);

		/*
		* get a _nByte size memory(all set to 0) in support of multi-thread
		*
		*@return the base address of the memory(success) or NULL(failure)
		*
		*/
		char* GetMemory(int _nByte);

		/*
		* release a _nByte size memory in support of multi-thread
		*
		*@parm _memory base address of the memory to release
		*
		*@return 0(success),-1(failure)
		*
		*/
		int	ReleaseMemory(char* _memory,int _nByte);

	private:
		CFreeList m_FreeListArray[FREE_LIST_ARRAY_LEN];


	};

}